// @FileName  :Scratch.c
// @Time      :2024/5/10 23:12
// @Author    :YKW
//# include <bits/stdc++.h>
//using namespace std;
# include <stdio.h>
# include <stdlib.h>
# include <math.h>
# include <string.h>
# include <stdlib.h>
# include <ctype.h>

char *getWord(char *word) {
    char *res, *p = (char *) malloc(sizeof(char) * 50);
    res = p;
    if (*word == ' ')
        *p++ = ' ';
    else if (ispunct(*word) && (*word != '_')) //获取一堆符号符号
        while (ispunct(*word) && (*word != '_'))*p++ = *word, word++;
    else if (isalnum(*word) || (*word == '_')) //获取一个变量/函数名
        while (isalnum(*word) || (*word == '_'))*p++ = *word, word++;
    else
        while (!(ispunct(*word) || isalnum(*word)) && strlen(word) > 0)word++;
    *p = '\0';
    return res;
}

int cmp(const void *a, const void *b) {
    char *p = (char *) a, *q = (char *) b;
//    while (*p++ == *q++);
//    return *q - *p;//字典序
    return strcmp(p, q);//字典升序
}

char *buffer;
char ans[100][100];
char *tmp;
int cnt;

int main() {
    buffer = (char *) malloc(1024 * sizeof(char));
    gets(buffer);
    while (strlen(buffer) > 0) {
        tmp = getWord(buffer);
        buffer += strlen(tmp);
        if (strlen(tmp) == 0 || isdigit(tmp[0]) || (ispunct(*tmp) && (*tmp != '_'))) continue;
        strcpy(ans[cnt++], tmp);
//        printf("%s\n", tmp);
    }
    qsort(ans, cnt, sizeof(ans[0]), cmp);
    printf("%s ", ans[0]);
    for (int i = 1; i < cnt; i++)
        if (strcmp(ans[i - 1], ans[i]) != 0)//去重
            printf("%s ", ans[i]);
}

/*网络版本
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<ctype.h>
#include<stdbool.h>
struct sen{
	char con[300];
}sentance[300];
int i,j,k,cnt=0;
char s[2000],tmp[2000];
int isNotSign(char s);		//判断是否为标识符
int cmp(const void*p1,const void*p2);
int main()
{
	gets(s);				//读取字符串 (注意有空格所以scanf不行)
	for(i=0;i<strlen(s);i++)
	{
		if(isNotSign(s[i])==1) //如果是标识符
		{
			for(j=i;j<strlen(s);j++)
			{
				if(isNotSign(s[j])==0)  //找到结尾
				{
					break;
				}
			}
			memset(tmp,0,sizeof(tmp));
			for(k=0;k<j-i;k++)
			{
				tmp[k]=s[i+k]; //tmp存储的是标识符
			}
			strcpy(sentance[cnt].con,tmp);
			cnt++; //标识符个数加一
			i=j;	//跳过标识符
		}
	}
	qsort(sentance,cnt,sizeof(struct sen),cmp);//排序
	for(i=0;i<cnt;i++)
	{
		int flag=0;   //判断是否为纯数字，flag=0 表示是纯数字，1 表示不是
		for(j=0;j<strlen(sentance[i].con);j++)
		{
			if(sentance[i].con[j]<'0'|| sentance[i].con[j]>'9')
			{
					flag=1;
			}
		}
		if(flag==0) //如果是纯数字
		{
			memset(sentance[i].con,0,sizeof(sentance[i].con));//删去
		}
	}
	for(i=0;i<cnt;i++)
	{
		for(j=i;j<cnt;j++)
		{
			if(j==i) continue;	//跳过
			else if(strcmp(sentance[i].con,sentance[j].con)==0)	memset(sentance[j].con,0,sizeof(sentance[j].con)); //去重
		}
	}
	qsort(sentance,cnt,sizeof(struct sen),cmp);
	for(i=0;i<cnt;i++)
	{
		if(sentance[i].con[0]!='\0')
		printf("%s ",sentance[i].con); //输出
	}
	return 0;
}
int isNotSign(char s)
{
	if((s>='a' && s<='z') || (s>='A' && s<='Z') || s=='_' || (s>='0' && s<='9')) //是标识符
			return 1;
	else 	return 0;
}
int cmp(const void*p1,const void*p2)
{
	struct sen *a=(struct sen*)p1;
	struct sen *b=(struct sen*)p2;
	return strcmp(b->con,a->con);
}

 */